package com.zm.admin.zmeng.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zm.admin.annotation.SysLogTag;
import com.zm.admin.zmeng.domain.ZmMenu;
import com.zm.admin.zmeng.dto.MenuDto;
import com.zm.admin.zmeng.mapper.ZmMenuMapper;
import com.zm.admin.utils.ResultBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;

/***
 *
 * @Auther: MuYun
 * @Date: 2022/9/26 22:18
 * @Description： 菜单相关接口
 *
 */
@RestController
@RequestMapping("/menu")
public class MenuController {

    private static Logger logger= LoggerFactory.getLogger(LoginController.class);

    @Resource
    private ZmMenuMapper zmMenuMapper;

    /**
     * 获取菜单树
     * @return
     */
    @RequestMapping("/getMenuTree")
    public ResultBean getMenuTree(){
        ResultBean resultBean=new ResultBean();
        QueryWrapper<ZmMenu> wrapper=new QueryWrapper<>();
        try{
            List<ZmMenu> zmMenuList = zmMenuMapper.selectList(wrapper.lambda().gt(ZmMenu::getStatus,"-1"));
            TreeNodeConfig nodeConfig=new TreeNodeConfig();
            nodeConfig.setIdKey("id");
            nodeConfig.setParentIdKey("parentId");
            nodeConfig.setNameKey("menuName");
            nodeConfig.setWeightKey("orderNum");
            List<Tree<String>> treeList = this.getTree(zmMenuList,nodeConfig);
            //logger.info("菜单树：{}",treeList);
            resultBean.setCode(ResultBean.CODE_SUCCESS).setData(treeList);
        }catch (Exception e){
            logger.error("获取菜单树接口出错:{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
        }
        return resultBean;
    }

    /**
     * 获取全局下的有子级菜单id和name
     * @return
     */
    @RequestMapping("/getHasChildMenu")
    public ResultBean getHasChildMenu(){
        ResultBean resultBean=new ResultBean();
        HashMap<String,Collection<String>> map=new HashMap<>();
        List<ZmMenu> zmMenus = new ArrayList<>();
        try{
            zmMenus=zmMenuMapper.getHasChildMenu();
            List<String> nameList=new ArrayList<>();
            List<String> idList=new ArrayList<>();
            //为了让他俩的索引一致，id与name对应，前端好操作
            for(ZmMenu menu:zmMenus){
                idList.add(menu.getId().toString());
                nameList.add(menu.getMenuName());
            }
            map.put("idList",idList);
            map.put("nameList",nameList);
            resultBean.setCode(ResultBean.CODE_SUCCESS).setData(map);
        }catch (Exception e){
            resultBean.setCode(ResultBean.CODE_ERROR);
            logger.error("获取一、二级组织接口报错：{}",e);
        }
        return resultBean;
    }


    /**
     * 模糊查询
     * @param menu
     * @return
     */
    @RequestMapping("/screen")
    @SysLogTag(desc = " 菜单模糊查询")
    public ResultBean screen(ZmMenu menu){
        ResultBean resultBean=new ResultBean();
        try{
            QueryWrapper<ZmMenu> wrapper=new QueryWrapper<>();
            if(StrUtil.isNotEmpty(menu.getMenuName())){
                wrapper.lambda().like(ZmMenu::getMenuName,menu.getMenuName());
            }
            if(StrUtil.isNotEmpty(menu.getPermission())){
                wrapper.lambda().like(ZmMenu::getPermission,menu.getPermission());
            }
            if(StrUtil.isNotEmpty(menu.getStatus())){
                wrapper.lambda().eq(ZmMenu::getStatus,menu.getStatus());
            }
            wrapper.lambda().ne(ZmMenu::getStatus,"-1");
            List<ZmMenu> zmMenus = zmMenuMapper.selectList(wrapper);
            resultBean.setCode(ResultBean.CODE_SUCCESS).setData(zmMenus);
        }catch (Exception e){
            logger.error("菜单模糊查询接口出错:{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
        }
        return resultBean;
    }

    /**
     * 查询所有的菜单标识做唯一校验
     * @return
     */
    @RequestMapping("/getAllMenuPermission")
    public ResultBean getAllMenuPermission(){
        ResultBean resultBean=new ResultBean();
        try{
            List<String> list = zmMenuMapper.selectAllPermission();
            resultBean.setCode(ResultBean.CODE_SUCCESS).setData(list);
        }catch (Exception e){
            logger.error("查询所有菜单标识接口出错:{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
        }
        return resultBean;
    }

    /**
     * 查出所有包含子级菜单的菜单id,在新增或修改用户的菜单权限时进行过滤
     * @return
     */
    @RequestMapping("/queryChildMenuId")
    public ResultBean queryChildMenuId(){
        ResultBean resultBean=new ResultBean();
        try{
            List<String> idList = zmMenuMapper.queryChildMenuId();
            resultBean.setCode(ResultBean.CODE_SUCCESS).setData(idList);
        }catch (Exception e){
            logger.error("查询所有菜单标识接口出错:{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
        }
        return resultBean;
    }

    /**
     * 根据权限码获取菜单
     * @param perm
     * @return
     */
    @RequestMapping("/getMenuByPerm")
    public ResultBean getMenuByPerm(@RequestParam(value = "perm") String perm){
        ResultBean resultBean=new ResultBean();
        ZmMenu zmMenu=null;
        logger.info("看看权限码：{}",perm);
        if(StrUtil.isEmpty(perm)){
            return resultBean.setData(null).setCode(ResultBean.CODE_SUCCESS);
        }
        try{
            QueryWrapper<ZmMenu> wrapper=new QueryWrapper<>();
            wrapper.lambda().eq(ZmMenu::getPermission, perm);
            wrapper.lambda().eq(ZmMenu::getStatus,"1");
            zmMenu = zmMenuMapper.selectOne(wrapper);
            resultBean.setData(zmMenu.getId()).setCode(ResultBean.CODE_SUCCESS);
        }catch (Exception e){
            logger.error("根据权限码获取菜单接口报错:{}",e);
        }
        return resultBean;
    }

    /**
     * 新增
     * @param menu
     * @return
     */
    @RequestMapping("/add")
    @SysLogTag(desc = " 菜单新增")
    public ResultBean add(ZmMenu menu){
        ResultBean resultBean=new ResultBean();
        try {
            menu.setCreateTime(DateUtil.date());
            menu.setCreateBy("等待开发捏");
            if(StrUtil.isEmpty(menu.getPath())){
                menu.setPath("");
            }
            zmMenuMapper.insert(menu);
            resultBean.setCode(ResultBean.CODE_SUCCESS);
        }catch (Exception e){
            logger.error("菜单新增接口出错:{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
        }
        return resultBean;
    }

    /**
     * 修改
     * @param menu
     * @return
     */
    @RequestMapping("/update")
    @SysLogTag(desc = " 菜单修改")
    public ResultBean update(ZmMenu menu){
        ResultBean resultBean=new ResultBean();
        try{
            menu.setUpdateTime(DateUtil.date());
            menu.setUpdateBy("依然是等待开发捏");
            zmMenuMapper.updateById(menu);
            resultBean.setCode(ResultBean.CODE_SUCCESS);
        }catch (Exception e){
            logger.error("菜单修改接口出错:{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
        }
        return resultBean;
    }
    /**
     * 删除
     * @param id
     * @return
     */
    @RequestMapping("/del")
    @SysLogTag(desc = " 菜单删除")
    public ResultBean del(@RequestParam(value = "id") String id){
        ResultBean resultBean=new ResultBean();
        List<String> list=new ArrayList<>();
        try{
            list = getChildMenuIds(id);//子级菜单id
            list.add(id);//本菜单id
            zmMenuMapper.del(list);
            resultBean.setCode(ResultBean.CODE_SUCCESS);
        }catch (Exception e){
            logger.error("菜单删除接口报错：{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
        }
        return resultBean;
    }


    /*一些工具方法捏*/
    // 查询所有子菜单ID
    public List<String> getChildMenuIds(String parentId) {
        List<String> childIds = new ArrayList<>();
        List<String> list = zmMenuMapper.queryChildMenuId(parentId);
        for (String childId : list) {
            childIds.add(childId);
            childIds.addAll(getChildMenuIds(childId)); // 递归查询子菜单的子菜单
        }
        return childIds;
    }

    public List<Tree<String>> getTree(List<ZmMenu> zmMenuList,TreeNodeConfig nodeConfig){
        List<Tree<String>> list=TreeUtil.build(zmMenuList,"0",nodeConfig,(menu,tree)->{
            tree.setId(menu.getId());
            tree.setParentId(menu.getParentId());
            if(!"0".equals(menu.getId())){
                tree.setWeight(menu.getOrderNum());
                tree.setName(menu.getMenuName());
                //拓展属性
                tree.putExtra("isBlank",menu.getIsBlank());
                tree.putExtra("isShow",menu.getIsShow());
                tree.putExtra("icon",menu.getIcon());
                tree.putExtra("url",menu.getUrl());
                tree.putExtra("path",menu.getPath());
                tree.putExtra("type",menu.getType());
                tree.putExtra("status",menu.getStatus());
                tree.putExtra("permission",menu.getPermission());
                tree.putExtra("createTime",parseTime(menu.getCreateTime()));
            }
            //如果不是一级菜单且不是祖级菜单，则查父菜单名称
            if(!"0".equals(menu.getParentId())&&!"0".equals(menu.getId())){
                ZmMenu parentMenu = zmMenuMapper.selectById(menu.getParentId());
                tree.putExtra("parentName",parentMenu.getMenuName());
            }
        });
        return list;
    }


    public static String parseTime(Date date){
        String time="";
        time=DateUtil.format(date,"yyyy-MM-dd HH:mm");
        return time;
    }
}
